#include "stdafx.h"
#include "TypeConvert.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//------------------------------------------------------------------------------------------
// Macros....
//------------------------------------------------------------------------------------------
#define BUFFER_ALLOCATION( var ) TCHAR var[16384];

#define BUFFER_RETURN( buffer, result, incoming )	bool bOK = (-1 != result);			\
	assert( bOK );						\
	incoming = (bOK) ? buffer : _T(""); \
	return bOK;

#define PARSE_RETURN( result )						assert( result );					\
	return result;

//
// Converting from char
//
bool TypeConvert::charTowchar_t(char* pszIn, wchar_t* pszOut)
{
	if (NULL == pszIn || NULL == pszOut)
	{
		return false;
	}

	size_t origsize = strlen(pszIn) + 1;
	int iRtn = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszIn, origsize, pszOut, origsize);
	assert ( 0 != iRtn);

	return true;
}

//
// Converting from wchar_t
//
bool TypeConvert::wchar_tTochar(wchar_t* pszIn, char* pszOut)
{
	if (NULL == pszIn || NULL == pszOut)
	{
		return false;
	}

	size_t iLen = wcslen(pszIn) * 2 + 1;
	int iRtn = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pszIn, -1, pszOut, iLen, NULL, NULL);
	assert (0 != iRtn);

	return true;
}

//
// Converting from CString
//
bool TypeConvert::cstringTochar(CString strIn, char* pszOut)
{
	if (strIn.IsEmpty() || NULL == pszOut)
	{
		return false;
	}

	int iLen = strIn.GetLength();
	memset(pszOut, 0, iLen + 1);

	wchar_t* pBuffer = strIn.GetBuffer();
	bool es = TypeConvert::wchar_tTochar(pBuffer, pszOut);
	ASSERT(es);

	strIn.ReleaseBuffer();

	return true;
}

bool TypeConvert::cstringTowchar_t(CString strIn, wchar_t* pszOut)
{
	if (strIn.IsEmpty() || NULL == pszOut)
	{
		return false;
	}

	int iLen = strIn.GetLength();
	char* pszTem = (char*)malloc((iLen + 1) * sizeof(char));
	memset(pszTem, 0, iLen + 1);

	bool es = TypeConvert::cstringTochar(strIn, pszTem);
	if (true == es)
	{
		es = TypeConvert::charTowchar_t(pszTem, pszOut);
	}

	free(pszTem);

	return es;
}

bool TypeConvert::cstringTo_bstr_t(CString strIn, _bstr_t& bstrOut)
{
	if (strIn.IsEmpty())
		return false;

	_bstr_t bstrTem(strIn);
	bstrOut = bstrTem;
	return true;
}


//
// Converting from basic_string
//
bool TypeConvert::stringTochar(string strIn, char* pszOut)
{
	if (strIn.empty() || NULL == pszOut)
	{
		return false;
	}

	size_t iLen = strIn.length();
	memset(pszOut, 0, iLen + 1);

	// the size contains '/0', so we add it by one while copying
	//
	errno_t iRes = strcpy_s(pszOut, iLen + 1, strIn.c_str());   
	if (iRes)
	{
		return false;
	}

	return true;
}

bool TypeConvert::stringTowchar_t(string strIn, wchar_t* pszOut)
{
	if(strIn.empty() || NULL == pszOut)
		return false;

	size_t iLen = strIn.length();
	char* pszTem = (char*)malloc((iLen + 1) * sizeof(char));
	bool es = TypeConvert::stringTochar(strIn, pszTem);
	if (true == es)
	{
		es = TypeConvert::charTowchar_t(pszTem, pszOut);
	}

	free(pszTem);

	return es;
}

bool TypeConvert::stringTocstring(string strIn, CString& strOut)
{
	if (strIn.empty())
	{
		return false;
	}

	CString strTem(strIn.c_str());
	strOut = strTem;

	return true;
}

bool TypeConvert::stringTo_bstr_t(string strIn, _bstr_t& bstrOut)
{
	if (strIn.empty())
		return false;

	_bstr_t bstrTem(strIn.c_str());

	bstrOut = bstrTem;

	return true;
}

//
// Converting from _bstr_t
//
bool TypeConvert::_bstr_tTostring(_bstr_t bstrIn, string& strOut)
{
	string basicstring((char *)bstrIn);

	strOut = basicstring;

	return true;
}

bool TypeConvert::_bstr_tTochar(_bstr_t bstrIn, char* pszOut)
{
	unsigned int len = bstrIn.length();
	memset(pszOut, 0, len + 1);

	if (0 == strcpy_s(pszOut, len + 1, (char*)bstrIn))	
		return true;
	else
		return false;
}

bool TypeConvert::_bstr_tTowchar_t(_bstr_t bstrIn, wchar_t* pszOut)
{
	unsigned int len = bstrIn.length();
	memset(pszOut, 0, len + 1);

	if (0 == wcscpy_s(pszOut, len + 1, (wchar_t *)bstrIn))
		return true;
	else
		return false;
}

bool TypeConvert::_bstr_tTocstring(_bstr_t bstrIn, CString& cstrOut)
{
	CString cstrTem((char*)bstrIn);
	cstrOut = cstrTem;
	return true;
}

//
//bool TypeConvert::StringTochar(String^ strIn, char* pszOut)
//{
//    if (strIn == String::Empty || NULL == pszOut )
//    {
//        return false;
//    }
//
//    pin_ptr<const wchar_t> pwchar = PtrToStringChars(strIn);
//    size_t origsize = wcslen(pwchar) + 1;
//    size_t convertedChars = 0;
//    memset(pszOut, 0, origsize);
//    wcstombs_s(&convertedChars, pszOut, origsize, pwchar, _TRUNCATE);
//
//    return true;
//}
//
//bool TypeConvert::StringTowchar_t(String^ strIn, wchar_t* pszOut)
//{
//    if (strIn == String::Empty || NULL == pszOut )
//    {
//        return false;
//    }
//
//    pin_ptr<const wchar_t> pwchar = PtrToStringChars(strIn);
//    size_t origsize = wcslen(pwchar) + 1;
//    memset(pszOut, 0, origsize);
//    wcscpy_s(pszOut,origsize, pwchar);
//
//    return true;
//}


// -----------------------------------------------------------------------------------------
// Native Data Type --> String
// -----------------------------------------------------------------------------------------
bool TypeConvert::NativeToString( BYTE bValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%d"), bValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( int iValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%d"), iValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( UINT iValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%u"), iValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( long lValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%ld"), lValue );
	BUFFER_RETURN( buffer, nResult, string );
}
bool TypeConvert::NativeToString( ULONG ulValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%lu"), ulValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( float fValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%.16f"), fValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( double dValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%.16g"), dValue );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( bool bValue, CString& string )
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%d"), bValue ? 1 : 0 );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString( LPGUID pGuid, CString& string)
{
	BUFFER_ALLOCATION( buffer );
	int nResult = ::swprintf( buffer, 16384, _T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
		pGuid->Data1, pGuid->Data2, pGuid->Data3,
		pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2],
		pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5],
		pGuid->Data4[6], pGuid->Data4[7] );
	BUFFER_RETURN( buffer, nResult, string );
}

bool TypeConvert::NativeToString(CLSID clsid, CString& string)
{
	//convert the GUID into a key
	LPOLESTR strKey;
	StringFromCLSID(clsid,&strKey);
	string = strKey;
	CoTaskMemFree(strKey);
	return true;
}

// -----------------------------------------------------------------------------------------
// String --> Native Data Type
// -----------------------------------------------------------------------------------------
bool TypeConvert::StringToNative( const CString& string, BYTE* bValue )
{
	int iValue = 0;
	bool bOK = StringToNative( string, &iValue );
	if (bOK)
	{
		*bValue = (BYTE)iValue;
	}
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, int* iValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%d"), iValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, UINT* iValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%u"), iValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, long* lValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%ld"), lValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, ULONG* ulValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%lu"), ulValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, float* fValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%f"), fValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, double* dValue )
{
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%lf"), dValue ));
	PARSE_RETURN( bOK );
}

bool TypeConvert::StringToNative( const CString& string, bool* bValue )
{
	int iValue = 0;
	bool bOK = (1 == ::swscanf_s( string.GetString(), _T("%d"), &iValue ));
	if (bOK)
	{
		*bValue = (iValue != 0);
	}
	PARSE_RETURN( bOK );
}